mirror of
				https://codeberg.org/forgejo/forgejo.git
				synced 2025-11-04 08:21:11 +00:00 
			
		
		
		
	This PR is part of #4767. It contains * a refactoring of validation error messages * adds the ability to send user-activities to distant federated servers Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/8792 Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org> Co-authored-by: Michael Jerger <michael.jerger@meissa-gmbh.de> Co-committed-by: Michael Jerger <michael.jerger@meissa-gmbh.de>
		
			
				
	
	
		
			246 lines
		
	
	
	
		
			7.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			246 lines
		
	
	
	
		
			7.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Copyright 2023, 2024 The Forgejo Authors. All rights reserved.
 | 
						|
// SPDX-License-Identifier: MIT
 | 
						|
 | 
						|
package forgefed
 | 
						|
 | 
						|
import (
 | 
						|
	"errors"
 | 
						|
	"reflect"
 | 
						|
	"strings"
 | 
						|
	"testing"
 | 
						|
	"time"
 | 
						|
 | 
						|
	"forgejo.org/modules/validation"
 | 
						|
 | 
						|
	ap "github.com/go-ap/activitypub"
 | 
						|
)
 | 
						|
 | 
						|
func Test_NewForgeUndoLike(t *testing.T) {
 | 
						|
	actorIRI := "https://repo.prod.meissa.de/api/v1/activitypub/user-id/1"
 | 
						|
	objectIRI := "https://codeberg.org/api/v1/activitypub/repository-id/1"
 | 
						|
	want := []byte(`{"type":"Undo","startTime":"2024-03-27T00:00:00Z",` +
 | 
						|
		`"actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1",` +
 | 
						|
		`"object":{` +
 | 
						|
		`"type":"Like",` +
 | 
						|
		`"actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1",` +
 | 
						|
		`"object":"https://codeberg.org/api/v1/activitypub/repository-id/1"}}`)
 | 
						|
 | 
						|
	startTime, _ := time.Parse("2006-Jan-02", "2024-Mar-27")
 | 
						|
	sut, err := NewForgeUndoLike(actorIRI, objectIRI, startTime)
 | 
						|
	if err != nil {
 | 
						|
		t.Errorf("unexpected error: %v\n", err)
 | 
						|
	}
 | 
						|
	if valid, _ := validation.IsValid(sut); !valid {
 | 
						|
		t.Errorf("sut expected to be valid: %v\n", sut.Validate())
 | 
						|
	}
 | 
						|
 | 
						|
	got, err := sut.MarshalJSON()
 | 
						|
	if err != nil {
 | 
						|
		t.Errorf("MarshalJSON() error = \"%v\"", err)
 | 
						|
		return
 | 
						|
	}
 | 
						|
	if !reflect.DeepEqual(got, want) {
 | 
						|
		t.Errorf("MarshalJSON() got = %q, want %q", got, want)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func Test_UndoLikeMarshalJSON(t *testing.T) {
 | 
						|
	type testPair struct {
 | 
						|
		item    ForgeUndoLike
 | 
						|
		want    []byte
 | 
						|
		wantErr error
 | 
						|
	}
 | 
						|
 | 
						|
	startTime, _ := time.Parse("2006-Jan-02", "2024-Mar-27")
 | 
						|
	like, _ := NewForgeLike("https://repo.prod.meissa.de/api/v1/activitypub/user-id/1", "https://codeberg.org/api/v1/activitypub/repository-id/1", startTime)
 | 
						|
	tests := map[string]testPair{
 | 
						|
		"empty": {
 | 
						|
			item: ForgeUndoLike{},
 | 
						|
			want: nil,
 | 
						|
		},
 | 
						|
		"valid": {
 | 
						|
			item: ForgeUndoLike{
 | 
						|
				Activity: ap.Activity{
 | 
						|
					StartTime: startTime,
 | 
						|
					Actor:     ap.IRI("https://repo.prod.meissa.de/api/v1/activitypub/user-id/1"),
 | 
						|
					Type:      "Undo",
 | 
						|
					Object:    like,
 | 
						|
				},
 | 
						|
			},
 | 
						|
			want: []byte(`{"type":"Undo",` +
 | 
						|
				`"startTime":"2024-03-27T00:00:00Z",` +
 | 
						|
				`"actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1",` +
 | 
						|
				`"object":{` +
 | 
						|
				`"type":"Like",` +
 | 
						|
				`"startTime":"2024-03-27T00:00:00Z",` +
 | 
						|
				`"actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1",` +
 | 
						|
				`"object":"https://codeberg.org/api/v1/activitypub/repository-id/1"}}`),
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	for name, tt := range tests {
 | 
						|
		t.Run(name, func(t *testing.T) {
 | 
						|
			got, err := tt.item.MarshalJSON()
 | 
						|
			if (err != nil || tt.wantErr != nil) && tt.wantErr.Error() != err.Error() {
 | 
						|
				t.Errorf("MarshalJSON() error = \"%v\", wantErr \"%v\"", err, tt.wantErr)
 | 
						|
				return
 | 
						|
			}
 | 
						|
			if !reflect.DeepEqual(got, tt.want) {
 | 
						|
				t.Errorf("MarshalJSON() got = %q\nwant %q", got, tt.want)
 | 
						|
			}
 | 
						|
		})
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func Test_UndoLikeUnmarshalJSON(t *testing.T) {
 | 
						|
	type testPair struct {
 | 
						|
		item    []byte
 | 
						|
		want    *ForgeUndoLike
 | 
						|
		wantErr error
 | 
						|
	}
 | 
						|
 | 
						|
	startTime, _ := time.Parse("2006-Jan-02", "2024-Mar-27")
 | 
						|
	like, _ := NewForgeLike("https://repo.prod.meissa.de/api/v1/activitypub/user-id/1", "https://codeberg.org/api/v1/activitypub/repository-id/1", startTime)
 | 
						|
 | 
						|
	tests := map[string]testPair{
 | 
						|
		"valid": {
 | 
						|
			item: []byte(`{"type":"Undo",` +
 | 
						|
				`"startTime":"2024-03-27T00:00:00Z",` +
 | 
						|
				`"actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1",` +
 | 
						|
				`"object":{` +
 | 
						|
				`"type":"Like",` +
 | 
						|
				`"startTime":"2024-03-27T00:00:00Z",` +
 | 
						|
				`"actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1",` +
 | 
						|
				`"object":"https://codeberg.org/api/v1/activitypub/repository-id/1"}}`),
 | 
						|
			want: &ForgeUndoLike{
 | 
						|
				Activity: ap.Activity{
 | 
						|
					StartTime: startTime,
 | 
						|
					Actor:     ap.IRI("https://repo.prod.meissa.de/api/v1/activitypub/user-id/1"),
 | 
						|
					Type:      "Undo",
 | 
						|
					Object:    like,
 | 
						|
				},
 | 
						|
			},
 | 
						|
			wantErr: nil,
 | 
						|
		},
 | 
						|
		"invalid": {
 | 
						|
			item:    []byte(`invalid JSON`),
 | 
						|
			want:    nil,
 | 
						|
			wantErr: errors.New("cannot parse JSON"),
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	for name, test := range tests {
 | 
						|
		t.Run(name, func(t *testing.T) {
 | 
						|
			got := new(ForgeUndoLike)
 | 
						|
			err := got.UnmarshalJSON(test.item)
 | 
						|
			if test.wantErr != nil {
 | 
						|
				if err == nil {
 | 
						|
					t.Errorf("UnmarshalJSON() error = nil, wantErr \"%v\"", test.wantErr)
 | 
						|
				} else if !strings.Contains(err.Error(), test.wantErr.Error()) {
 | 
						|
					t.Errorf("UnmarshalJSON() error = \"%v\", wantErr \"%v\"", err, test.wantErr)
 | 
						|
				}
 | 
						|
				return
 | 
						|
			}
 | 
						|
			remarshalledgot, _ := got.MarshalJSON()
 | 
						|
			remarshalledwant, _ := test.want.MarshalJSON()
 | 
						|
			if !reflect.DeepEqual(remarshalledgot, remarshalledwant) {
 | 
						|
				t.Errorf("UnmarshalJSON() got = %#v\nwant %#v", got, test.want)
 | 
						|
			}
 | 
						|
		})
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestActivityValidationUndo(t *testing.T) {
 | 
						|
	sut := new(ForgeUndoLike)
 | 
						|
 | 
						|
	_ = sut.UnmarshalJSON([]byte(`
 | 
						|
		{"type":"Undo",
 | 
						|
		 "startTime":"2024-03-27T00:00:00Z",
 | 
						|
		 "actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1",
 | 
						|
		 "object":{
 | 
						|
		   "type":"Like",
 | 
						|
		   "actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1",
 | 
						|
		   "object":"https://codeberg.org/api/v1/activitypub/repository-id/1"}}`))
 | 
						|
	if res, _ := validation.IsValid(sut); !res {
 | 
						|
		t.Errorf("sut expected to be valid: %v\n", sut.Validate())
 | 
						|
	}
 | 
						|
 | 
						|
	_ = sut.UnmarshalJSON([]byte(`
 | 
						|
		{"startTime":"2024-03-27T00:00:00Z",
 | 
						|
		"actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1",
 | 
						|
		"object":{
 | 
						|
		  "type":"Like",
 | 
						|
		  "startTime":"2024-03-27T00:00:00Z",
 | 
						|
		  "actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1",
 | 
						|
		  "object":"https://codeberg.org/api/v1/activitypub/repository-id/1"}}`))
 | 
						|
	if err := validateAndCheckError(sut, "Value type should not be empty"); err != nil {
 | 
						|
		t.Error(*err)
 | 
						|
	}
 | 
						|
 | 
						|
	_ = sut.UnmarshalJSON([]byte(`
 | 
						|
		{"type":"Undo",
 | 
						|
		 "startTime":"2024-03-27T00:00:00Z",
 | 
						|
		 "object":{
 | 
						|
		   "type":"Like",
 | 
						|
		   "actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1",
 | 
						|
		   "object":"https://codeberg.org/api/v1/activitypub/repository-id/1"}}`))
 | 
						|
	if err := validateAndCheckError(sut, "Actor should not be nil."); err != nil {
 | 
						|
		t.Error(*err)
 | 
						|
	}
 | 
						|
 | 
						|
	_ = sut.UnmarshalJSON([]byte(`
 | 
						|
		{"type":"Undo",
 | 
						|
		"startTime":"2024-03-27T00:00:00Z",
 | 
						|
		"actor":"string",
 | 
						|
		"object":{
 | 
						|
		"type":"Like",
 | 
						|
			"actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1",
 | 
						|
			"object":"https://codeberg.org/api/v1/activitypub/repository-id/1"}}`))
 | 
						|
	if err := validateAndCheckError(sut, "Actor should not be nil."); err != nil {
 | 
						|
		t.Error(*err)
 | 
						|
	}
 | 
						|
 | 
						|
	_ = sut.UnmarshalJSON([]byte(`
 | 
						|
		{"type":"Undo",
 | 
						|
		"startTime":"2024-03-27T00:00:00Z",
 | 
						|
		"actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1"
 | 
						|
		}`))
 | 
						|
	if err := validateAndCheckError(sut, "object should not be empty."); err != nil {
 | 
						|
		t.Error(*err)
 | 
						|
	}
 | 
						|
 | 
						|
	_ = sut.UnmarshalJSON([]byte(`
 | 
						|
		{"type":"Undo",
 | 
						|
		"startTime":"2024-03-27T00:00:00Z",
 | 
						|
		"actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1",
 | 
						|
		"object":{
 | 
						|
		  "startTime":"2024-03-27T00:00:00Z",
 | 
						|
		  "actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1",
 | 
						|
		  "object":"https://codeberg.org/api/v1/activitypub/repository-id/1"}}`))
 | 
						|
	if err := validateAndCheckError(sut, "object is not of type Activity"); err != nil {
 | 
						|
		t.Error(*err)
 | 
						|
	}
 | 
						|
 | 
						|
	_ = sut.UnmarshalJSON([]byte(`
 | 
						|
		{"type":"Undo",
 | 
						|
		"startTime":"2024-03-27T00:00:00Z",
 | 
						|
		"actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1",
 | 
						|
		"object":{
 | 
						|
		  "type":"Like",
 | 
						|
		  "object":""}}`))
 | 
						|
	if err := validateAndCheckError(sut, "Object.Actor should not be nil."); err != nil {
 | 
						|
		t.Error(*err)
 | 
						|
	}
 | 
						|
 | 
						|
	_ = sut.UnmarshalJSON([]byte(`
 | 
						|
		{"type":"Undo",
 | 
						|
		"startTime":"2024-03-27T00:00:00Z",
 | 
						|
		"actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1",
 | 
						|
		"object":{
 | 
						|
		  "type":"Like",
 | 
						|
		  "startTime":"2024-03-27T00:00:00Z",
 | 
						|
		  "actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1"}}`))
 | 
						|
	if err := validateAndCheckError(sut, "Object.Object should not be nil."); err != nil {
 | 
						|
		t.Error(*err)
 | 
						|
	}
 | 
						|
}
 |