From 53c634a7f635768f13501bade412c881d89a097b Mon Sep 17 00:00:00 2001 From: Wil Simpson Date: Sun, 17 Mar 2024 17:33:21 -0400 Subject: [PATCH] Added chat server coverage --- coverage.out | 322 +++++++++---------- pkg/model/errors.go | 2 + pkg/srv/chat.go | 81 ++--- pkg/srv/chat_test.go | 747 ++++++++++++++++++++++++++++++++++++------- 4 files changed, 829 insertions(+), 323 deletions(-) diff --git a/coverage.out b/coverage.out index 02f79dd..61c3aa7 100644 --- a/coverage.out +++ b/coverage.out @@ -134,165 +134,163 @@ github.com/ShatteredRealms/go-backend/pkg/srv/character.go:514.3,514.38 1 4 github.com/ShatteredRealms/go-backend/pkg/srv/character.go:514.38,516.4 1 0 github.com/ShatteredRealms/go-backend/pkg/srv/character.go:518.3,518.24 1 4 github.com/ShatteredRealms/go-backend/pkg/srv/character.go:521.2,521.21 1 16 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:40.57,43.2 2 62 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:48.9,50.16 2 6 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:50.16,53.3 2 1 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:56.2,56.59 1 5 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:56.59,58.3 1 1 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:61.2,61.72 1 4 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:61.72,63.17 2 4 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:63.17,66.4 2 4 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:69.2,71.6 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:71.6,73.17 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:73.17,76.4 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:78.3,83.17 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:83.17,86.4 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:93.9,95.16 2 7 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:95.16,98.3 2 1 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:101.2,101.59 1 6 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:101.59,103.3 1 1 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:105.2,106.16 2 5 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:106.16,108.3 1 4 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:110.2,111.6 2 1 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:111.6,113.17 2 1 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:113.17,116.4 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:118.3,123.17 2 1 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:123.17,126.4 2 1 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:133.27,135.16 2 11 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:135.16,138.3 2 2 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:141.2,141.59 1 9 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:141.59,144.3 2 1 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:145.2,149.16 2 8 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:149.16,152.3 2 3 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:156.2,156.72 1 5 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:156.72,158.17 2 3 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:158.17,161.4 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:163.3,164.17 2 3 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:164.17,167.4 2 1 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:169.3,170.36 2 2 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:170.36,171.45 1 1 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:171.45,173.10 2 1 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:176.3,176.15 1 2 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:176.15,179.4 2 1 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:182.2,188.16 2 3 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:188.16,191.3 2 1 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:193.2,193.30 1 2 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:199.27,201.16 2 9 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:201.16,204.3 2 2 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:207.2,207.59 1 7 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:207.59,209.3 1 1 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:211.2,214.16 1 6 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:214.16,216.3 1 3 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:218.2,219.16 2 3 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:219.16,222.3 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:223.2,224.16 2 3 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:224.16,226.3 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:228.2,233.16 1 3 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:233.16,236.3 2 1 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:238.2,238.30 1 2 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:244.28,246.16 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:246.16,249.3 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:252.2,252.72 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:252.72,254.3 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:256.2,257.16 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:257.16,260.3 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:262.2,262.22 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:268.27,270.16 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:270.16,273.3 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:276.2,276.72 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:276.72,278.3 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:280.2,288.16 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:288.16,289.44 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:289.44,291.4 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:293.3,294.76 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:297.2,297.30 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:303.27,305.16 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:305.16,308.3 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:311.2,311.72 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:311.72,313.3 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:315.2,318.16 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:318.16,319.45 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:319.45,321.4 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:323.3,324.71 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:327.2,327.30 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:333.27,335.16 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:335.16,338.3 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:341.2,341.72 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:341.72,343.3 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:345.2,346.16 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:346.16,347.45 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:347.45,349.4 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:351.3,352.69 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:355.2,355.30 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:361.29,363.16 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:363.16,366.3 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:369.2,369.72 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:369.72,371.3 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:373.2,374.16 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:374.16,377.3 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:379.2,379.29 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:385.29,387.16 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:387.16,390.3 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:393.2,393.59 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:393.59,395.3 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:397.2,398.16 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:398.16,401.3 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:402.2,403.16 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:403.16,405.3 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:407.2,408.16 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:408.16,411.3 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:413.2,413.29 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:419.27,421.16 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:421.16,424.3 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:427.2,427.72 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:427.72,429.3 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:431.2,432.49 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:433.32,435.17 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:435.17,438.4 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:439.3,440.17 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:440.17,442.4 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:443.3,443.42 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:445.30,446.38 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:448.10,450.37 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:453.2,459.16 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:459.16,460.44 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:460.44,462.4 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:464.3,465.77 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:468.2,468.30 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:474.33,481.16 2 34 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:481.16,483.3 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:485.2,492.16 2 34 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:492.16,494.3 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:496.2,498.8 1 34 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:502.88,509.16 2 29 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:509.16,512.3 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:514.2,517.8 1 29 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:520.132,522.16 2 19 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:522.16,525.3 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:527.2,528.16 2 19 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:528.16,531.3 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:533.2,536.16 2 19 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:536.16,539.3 2 4 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:541.2,541.39 1 15 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:542.30,543.38 1 3 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:543.38,544.25 1 1 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:544.25,546.5 1 1 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:549.32,550.38 1 12 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:550.38,551.29 1 8 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:551.29,553.5 1 8 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:556.10,558.37 2 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:561.2,561.73 1 6 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:564.107,566.16 2 4 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:566.16,568.3 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:570.2,572.16 2 4 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:572.16,575.3 2 1 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:577.2,577.50 1 3 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:577.50,579.17 2 2 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:579.17,582.4 2 1 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:584.3,584.36 1 1 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:584.36,585.31 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:585.31,587.5 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:591.2,591.30 1 2 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:39.57,42.2 2 62 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:47.9,49.16 2 7 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:49.16,52.3 2 1 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:55.2,55.59 1 6 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:55.59,57.3 1 1 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:60.2,60.72 1 5 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:60.72,62.17 2 4 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:62.17,65.4 2 3 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:68.2,70.6 2 2 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:70.6,72.17 2 2 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:72.17,75.4 2 0 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:77.3,82.17 2 2 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:82.17,85.4 2 2 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:92.9,94.16 2 8 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:94.16,97.3 2 1 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:100.2,100.59 1 7 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:100.59,102.3 1 1 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:104.2,105.30 2 6 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:105.30,106.73 1 2 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:106.73,108.4 1 1 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:109.8,109.23 1 4 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:109.23,111.3 1 2 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:113.2,114.6 2 3 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:114.6,116.17 2 3 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:116.17,119.4 2 0 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:121.3,126.17 2 3 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:126.17,129.4 2 3 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:136.27,138.16 2 11 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:138.16,141.3 2 2 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:144.2,144.59 1 9 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:144.59,147.3 2 1 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:148.2,152.16 2 8 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:152.16,155.3 2 3 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:159.2,159.72 1 5 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:159.72,161.17 2 4 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:161.17,164.4 2 0 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:166.3,167.17 2 4 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:167.17,170.4 2 1 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:172.3,173.36 2 3 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:173.36,174.45 1 2 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:174.45,176.10 2 2 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:179.3,179.15 1 3 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:179.15,182.4 2 1 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:185.2,191.16 2 3 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:191.16,194.3 2 1 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:196.2,196.30 1 2 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:202.27,204.16 2 9 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:204.16,207.3 2 2 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:210.2,210.59 1 7 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:210.59,212.3 1 1 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:214.2,217.16 1 6 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:217.16,219.3 1 3 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:221.2,222.16 2 3 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:222.16,225.3 2 0 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:226.2,227.16 2 3 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:227.16,229.3 1 0 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:231.2,236.16 1 3 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:236.16,239.3 2 1 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:241.2,241.30 1 2 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:247.28,249.16 2 7 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:249.16,252.3 2 2 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:255.2,255.72 1 5 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:255.72,257.3 1 2 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:259.2,260.16 2 3 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:260.16,263.3 2 1 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:265.2,265.14 1 2 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:265.14,267.3 1 1 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:269.2,269.22 1 1 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:275.27,277.16 2 7 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:277.16,280.3 2 2 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:283.2,283.72 1 5 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:283.72,285.3 1 2 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:287.2,295.16 2 3 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:295.16,296.44 1 2 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:296.44,298.4 1 1 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:300.3,301.76 2 1 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:304.2,304.30 1 1 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:310.27,312.16 2 7 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:312.16,315.3 2 2 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:318.2,318.72 1 5 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:318.72,320.3 1 2 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:322.2,325.16 2 3 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:325.16,326.45 1 2 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:326.45,328.4 1 1 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:330.3,331.71 2 1 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:334.2,334.30 1 1 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:340.27,342.16 2 7 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:342.16,345.3 2 2 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:348.2,348.72 1 5 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:348.72,350.3 1 2 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:352.2,353.16 2 3 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:353.16,354.45 1 2 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:354.45,356.4 1 1 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:358.3,359.69 2 1 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:362.2,362.30 1 1 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:368.29,370.16 2 6 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:370.16,373.3 2 2 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:376.2,376.72 1 4 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:376.72,378.3 1 2 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:380.2,381.16 2 2 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:381.16,384.3 2 1 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:386.2,386.29 1 1 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:392.29,394.16 2 9 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:394.16,397.3 2 2 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:400.2,400.59 1 7 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:400.59,402.3 1 1 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:404.2,405.30 2 6 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:405.30,406.73 1 1 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:406.73,408.4 1 0 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:409.8,409.43 1 5 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:409.43,412.3 2 2 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:414.2,415.16 2 4 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:415.16,418.3 2 1 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:420.2,420.29 1 3 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:426.27,428.16 2 8 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:428.16,431.3 2 2 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:434.2,434.72 1 6 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:434.72,436.3 1 3 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:438.2,439.16 2 3 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:439.16,442.3 2 0 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:443.2,444.16 2 3 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:444.16,446.3 1 0 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:448.2,454.16 2 3 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:454.16,455.44 1 2 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:455.44,457.4 1 1 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:459.3,460.77 2 1 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:463.2,463.30 1 1 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:469.33,476.16 2 84 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:476.16,478.3 1 0 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:480.2,487.16 2 84 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:487.16,489.3 1 0 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:491.2,493.8 1 84 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:497.88,504.16 2 40 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:504.16,507.3 2 0 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:509.2,512.8 1 40 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:515.132,517.16 2 26 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:517.16,520.3 2 0 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:522.2,523.16 2 26 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:523.16,526.3 2 0 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:528.2,529.16 2 26 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:529.16,532.3 2 5 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:534.2,534.22 1 21 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:534.22,536.3 1 1 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:538.2,538.39 1 20 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:538.39,540.3 1 7 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:542.2,542.23 1 13 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:545.107,547.16 2 4 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:547.16,549.3 1 0 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:551.2,553.16 2 4 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:553.16,556.3 2 1 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:558.2,558.50 1 3 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:558.50,560.17 2 3 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:560.17,563.4 2 1 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:565.3,565.36 1 2 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:565.36,566.31 1 1 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:566.31,568.5 1 1 +github.com/ShatteredRealms/go-backend/pkg/srv/chat.go:572.2,572.30 1 1 github.com/ShatteredRealms/go-backend/pkg/srv/connection.go:38.63,41.2 2 62 github.com/ShatteredRealms/go-backend/pkg/srv/connection.go:52.42,54.16 2 0 github.com/ShatteredRealms/go-backend/pkg/srv/connection.go:54.16,57.3 2 0 @@ -578,7 +576,7 @@ github.com/ShatteredRealms/go-backend/pkg/srv/servermanager.go:846.16,848.3 1 0 github.com/ShatteredRealms/go-backend/pkg/srv/servermanager.go:850.2,850.16 1 0 github.com/ShatteredRealms/go-backend/pkg/srv/servermanager.go:850.16,852.3 1 0 github.com/ShatteredRealms/go-backend/pkg/srv/servermanager.go:854.2,854.17 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/util.go:17.9,18.30 1 98 -github.com/ShatteredRealms/go-backend/pkg/srv/util.go:18.30,22.56 2 324 +github.com/ShatteredRealms/go-backend/pkg/srv/util.go:17.9,18.30 1 148 +github.com/ShatteredRealms/go-backend/pkg/srv/util.go:18.30,22.56 2 424 github.com/ShatteredRealms/go-backend/pkg/srv/util.go:22.56,24.4 1 0 -github.com/ShatteredRealms/go-backend/pkg/srv/util.go:27.2,27.12 1 98 +github.com/ShatteredRealms/go-backend/pkg/srv/util.go:27.2,27.12 1 148 diff --git a/pkg/model/errors.go b/pkg/model/errors.go index d490459..9563a31 100644 --- a/pkg/model/errors.go +++ b/pkg/model/errors.go @@ -23,6 +23,8 @@ var ( // ErrInvalidServerLocation thrown when a server location is unknown ErrInvalidServerLocation = errors.New("invalid server location") + ErrNotOwner = errors.New("not owner") + ErrUnauthorized = status.Error(codes.Unauthenticated, "not authorized") ErrDoesNotExist = status.Error(codes.InvalidArgument, "does not exist") ErrHandleRequest = status.Error(codes.Internal, "unable to handle request") diff --git a/pkg/srv/chat.go b/pkg/srv/chat.go index 84d39c7..53ff13a 100644 --- a/pkg/srv/chat.go +++ b/pkg/srv/chat.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "reflect" "github.com/Nerzal/gocloak/v13" chat "github.com/ShatteredRealms/go-backend/cmd/chat/app" @@ -103,7 +102,11 @@ func (s chatServiceServer) ConnectDirectMessage( } char, err := s.verifyUserOwnsCharacter(server.Context(), request) - if err != nil { + if err == model.ErrNotOwner { + if !claims.HasResourceRole(RoleChatChannelManage, model.ChatClientId) { + return model.ErrUnauthorized + } + } else if err != nil { return model.ErrUnauthorized } @@ -259,6 +262,10 @@ func (s chatServiceServer) GetChannel( return nil, status.Error(codes.Internal, "unable to get chat channel") } + if c == nil { + return nil, model.ErrDoesNotExist + } + return c.ToPb(), nil } @@ -394,17 +401,17 @@ func (s chatServiceServer) GetAuthorizedChatChannels( return nil, model.ErrUnauthorized } - srvCtx, err := s.serverContext(ctx) - if err != nil { - log.Logger.WithContext(ctx).Errorf("create server context: %v", err) - return nil, model.ErrHandleRequest - } - targetCharacterId, err := helpers.GetCharacterIdFromTarget(srvCtx, s.server.CharacterService, request) - if err != nil { + character, err := s.verifyUserOwnsCharacter(ctx, request) + if err == model.ErrNotOwner { + if !claims.HasResourceRole(RoleChatChannelManage, model.ChatClientId) { + return nil, status.Error(codes.PermissionDenied, model.ErrNotOwner.Error()) + } + } else if err != nil || character == nil { + log.Logger.WithContext(ctx).Infof("verify owns character failed: %v", err) return nil, err } - channels, err := s.server.ChatService.AuthorizedChannelsForCharacter(ctx, targetCharacterId) + channels, err := s.server.ChatService.AuthorizedChannelsForCharacter(ctx, uint(character.Id)) if err != nil { log.Logger.WithContext(ctx).Errorf("get authorized channels: %v", err) return nil, status.Error(codes.Internal, "unable to get channels") @@ -428,27 +435,15 @@ func (s chatServiceServer) UpdateUserChatChannelAuthorizations( return nil, model.ErrUnauthorized } - targetCharacterId := uint(0) - switch target := request.Character.Type.(type) { - case *pb.CharacterTarget_Name: - srvCtx, err := s.serverContext(ctx) - if err != nil { - log.Logger.WithContext(ctx).Errorf("create server context: %v", err) - return nil, model.ErrHandleRequest - } - targetChar, err := s.server.CharacterService.GetCharacter(srvCtx, request.Character) - if err != nil { - return nil, err - } - targetCharacterId = uint(targetChar.Id) - - case *pb.CharacterTarget_Id: - targetCharacterId = uint(target.Id) - - default: - log.Logger.WithContext(ctx).Errorf("target type unknown: %s", reflect.TypeOf(request.Character).Name()) + srvCtx, err := s.serverContext(ctx) + if err != nil { + log.Logger.WithContext(ctx).Errorf("create server context: %v", err) return nil, model.ErrHandleRequest } + targetCharacterId, err := helpers.GetCharacterIdFromTarget(srvCtx, s.server.CharacterService, request.Character) + if err != nil { + return nil, err + } err = s.server.ChatService.ChangeAuthorizationForCharacter( ctx, @@ -530,35 +525,21 @@ func (s chatServiceServer) verifyUserOwnsCharacter(ctx context.Context, request return nil, model.ErrHandleRequest } - chars, err := s.server.CharacterService.GetAllCharactersForUser(srvCtx, &pb.UserTarget{ - Target: &pb.UserTarget_Id{Id: claims.Subject}, - }) + character, err := s.server.CharacterService.GetCharacter(srvCtx, request) if err != nil { log.Logger.WithContext(ctx).Errorf("chat character service get for user: %v", err) return nil, status.Errorf(codes.Internal, "unable to verify character") } - switch target := request.Type.(type) { - case *pb.CharacterTarget_Id: - for _, c := range chars.Characters { - if c.Id == target.Id { - return c, nil - } - } - - case *pb.CharacterTarget_Name: - for _, c := range chars.Characters { - if c.Name == target.Name { - return c, nil - } - } + if character == nil { + return nil, status.Errorf(codes.Internal, "character does not exist") + } - default: - log.Logger.WithContext(ctx).Errorf("target type unknown: %+v", target) - return nil, model.ErrHandleRequest + if character.Owner != claims.Subject { + return character, model.ErrNotOwner } - return nil, status.Errorf(codes.Unauthenticated, "character not found") + return character, nil } func (s chatServiceServer) checkUserChannelAuth(ctx context.Context, userId string, channelId uint) error { diff --git a/pkg/srv/chat_test.go b/pkg/srv/chat_test.go index 12d09a4..2e90a74 100644 --- a/pkg/srv/chat_test.go +++ b/pkg/srv/chat_test.go @@ -8,6 +8,7 @@ import ( app "github.com/ShatteredRealms/go-backend/cmd/chat/app" "github.com/ShatteredRealms/go-backend/pkg/config" + "github.com/ShatteredRealms/go-backend/pkg/helpers" "github.com/ShatteredRealms/go-backend/pkg/log" "github.com/ShatteredRealms/go-backend/pkg/mocks" "github.com/ShatteredRealms/go-backend/pkg/model" @@ -21,6 +22,7 @@ import ( "github.com/sirupsen/logrus/hooks/test" "go.opentelemetry.io/otel" "go.uber.org/mock/gomock" + "google.golang.org/protobuf/types/known/emptypb" "gorm.io/gorm" ) @@ -44,6 +46,9 @@ var _ = Describe("Chat", func() { MaxBytes: 10e3, } kafkaWriter *kafka.Writer + + chatChannel *model.ChatChannel + character *model.Character ) BeforeEach(func() { @@ -65,12 +70,57 @@ var _ = Describe("Chat", func() { Expect(err).NotTo(HaveOccurred()) Expect(server).NotTo(BeNil()) + character = &model.Character{ + ID: 0, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + DeletedAt: 0, + OwnerId: *player.ID, + Name: faker.Username(), + Gender: "Male", + Realm: "Human", + PlayTime: 100, + Location: model.Location{ + World: faker.Username(), + X: 1.1, + Y: 1.2, + Z: 1.3, + Roll: 1.4, + Pitch: 1.5, + Yaw: 1.6, + }, + } + chatChannel = &model.ChatChannel{ + Model: gorm.Model{ + ID: 1, + CreatedAt: time.Now(), + UpdatedAt: time.Now(), + }, + Name: faker.Username(), + Dimension: faker.Username(), + } + hook.Reset() }) Context("with kafka", func() { - var character *model.Character - var chatChannel *model.ChatChannel + var ( + msg *pb.ChatMessage + writeMessageFunc = func(g Gomega) error { + err := kafkaConn.CreateTopics(kafka.TopicConfig{ + Topic: topicName, + NumPartitions: 1, + ReplicationFactor: 1, + }) + if err != nil { + return err + } + return kafkaWriter.WriteMessages(context.Background(), kafka.Message{ + Key: []byte(msg.CharacterName), + Value: []byte(msg.Message), + }) + } + ) BeforeEach(func() { Eventually(func(g Gomega) error { var err error @@ -97,50 +147,20 @@ var _ = Describe("Chat", func() { ReplicationFactor: 1, }) }).Within(time.Minute).Should(Succeed()) - character = &model.Character{ - ID: 0, - CreatedAt: time.Now(), - UpdatedAt: time.Now(), - DeletedAt: 0, - OwnerId: faker.Username(), - Name: faker.Username(), - Gender: "Male", - Realm: "Human", - PlayTime: 100, - Location: model.Location{ - World: faker.Username(), - X: 1.1, - Y: 1.2, - Z: 1.3, - Roll: 1.4, - Pitch: 1.5, - Yaw: 1.6, - }, - } - chatChannel = &model.ChatChannel{ - Model: gorm.Model{ - ID: 1, - CreatedAt: time.Now(), - UpdatedAt: time.Now(), - }, - Name: faker.Username(), - Dimension: faker.Username(), + msg = &pb.ChatMessage{ + Message: faker.Username(), + CharacterName: character.Name, } }) Describe("ConnectChannel", func() { var req *pb.ChatChannelTarget var mockInSrv *mocks.MockChatService_ConnectChannelServer - var msg *pb.ChatMessage BeforeEach(func() { req = &pb.ChatChannelTarget{ Id: 1, } mockInSrv = mocks.NewMockChatService_ConnectChannelServer(mockController) - msg = &pb.ChatMessage{ - Message: faker.Username(), - CharacterName: faker.Username(), - } }) When("given valid input", func() { @@ -148,23 +168,19 @@ var _ = Describe("Chat", func() { mockChatService.EXPECT().ChannelMessagesReader(gomock.Any(), uint(req.Id)).Return(kafka.NewReader(readerConfig)) mockInSrv.EXPECT().Context().Return(incAdminCtx).AnyTimes() mockInSrv.EXPECT().Send(gomock.Any()).Return(io.EOF) - Eventually(kafkaWriter.WriteMessages(context.Background(), kafka.Message{ - Key: []byte(msg.CharacterName), - Value: []byte(msg.Message), - })).Within(time.Second * 5).Should(Succeed()) + Eventually(writeMessageFunc).Within(time.Second * 15).Should(Succeed()) Expect(server.ConnectChannel(req, mockInSrv)).To(MatchError(io.EOF)) }) It("should work for users with chat permissions (player)", func() { mockChatService.EXPECT().ChannelMessagesReader(gomock.Any(), uint(req.Id)).Return(kafka.NewReader(readerConfig)) - mockCharService.EXPECT().GetAllCharactersForUser(gomock.Any(), gomock.Any()).Return(&pb.CharactersDetails{Characters: []*pb.CharacterDetails{character.ToPb()}}, nil) + mockCharService.EXPECT(). + GetAllCharactersForUser(gomock.Any(), gomock.Any()). + Return(&pb.CharactersDetails{Characters: []*pb.CharacterDetails{character.ToPb()}}, nil) mockChatService.EXPECT().AuthorizedChannelsForCharacter(gomock.Any(), character.ID).Return(model.ChatChannels{chatChannel}, nil) mockInSrv.EXPECT().Context().Return(incPlayerCtx).AnyTimes() mockInSrv.EXPECT().Send(gomock.Any()).Return(io.EOF) - Eventually(kafkaWriter.WriteMessages(context.Background(), kafka.Message{ - Key: []byte(msg.CharacterName), - Value: []byte(msg.Message), - })).Within(time.Second * 5).Should(Succeed()) + Eventually(writeMessageFunc).Within(time.Second * 15).Should(Succeed()) Expect(server.ConnectChannel(req, mockInSrv)).To(MatchError(io.EOF)) }) }) @@ -181,26 +197,26 @@ var _ = Describe("Chat", func() { }) It("should error on no permissions for chat channel (player)", func() { - mockCharService.EXPECT().GetAllCharactersForUser(gomock.Any(), gomock.Any()).Return(&pb.CharactersDetails{Characters: []*pb.CharacterDetails{character.ToPb()}}, nil) + mockCharService.EXPECT(). + GetAllCharactersForUser(gomock.Any(), gomock.Any()). + Return(&pb.CharactersDetails{Characters: []*pb.CharacterDetails{character.ToPb()}}, nil) mockChatService.EXPECT().AuthorizedChannelsForCharacter(gomock.Any(), character.ID).Return(model.ChatChannels{}, nil) mockInSrv.EXPECT().Context().Return(incPlayerCtx).AnyTimes() Expect(server.ConnectChannel(req, mockInSrv)).To(MatchError(model.ErrUnauthorized)) }) - It("should error on no permissions for chat channel due to no characters (player)", func() { - mockCharService.EXPECT().GetAllCharactersForUser(gomock.Any(), gomock.Any()).Return(&pb.CharactersDetails{Characters: []*pb.CharacterDetails{}}, nil) - mockInSrv.EXPECT().Context().Return(incPlayerCtx).AnyTimes() - Expect(server.ConnectChannel(req, mockInSrv)).To(MatchError(model.ErrUnauthorized)) - }) - It("should error if getting characters has errors", func() { - mockCharService.EXPECT().GetAllCharactersForUser(gomock.Any(), gomock.Any()).Return(&pb.CharactersDetails{Characters: []*pb.CharacterDetails{}}, fakeErr) + mockCharService.EXPECT(). + GetAllCharactersForUser(gomock.Any(), gomock.Any()). + Return(nil, fakeErr) mockInSrv.EXPECT().Context().Return(incPlayerCtx).AnyTimes() Expect(server.ConnectChannel(req, mockInSrv)).To(MatchError(model.ErrHandleRequest)) }) It("should error if getting authorized channels for character has errors", func() { - mockCharService.EXPECT().GetAllCharactersForUser(gomock.Any(), gomock.Any()).Return(&pb.CharactersDetails{Characters: []*pb.CharacterDetails{character.ToPb()}}, nil) + mockCharService.EXPECT(). + GetAllCharactersForUser(gomock.Any(), gomock.Any()). + Return(&pb.CharactersDetails{Characters: []*pb.CharacterDetails{character.ToPb()}}, nil) mockChatService.EXPECT().AuthorizedChannelsForCharacter(gomock.Any(), character.ID).Return(nil, fakeErr) mockInSrv.EXPECT().Context().Return(incPlayerCtx).AnyTimes() Expect(server.ConnectChannel(req, mockInSrv)).To(MatchError(model.ErrHandleRequest)) @@ -211,40 +227,48 @@ var _ = Describe("Chat", func() { Describe("ConnectDirectMessage", func() { var req *pb.CharacterTarget var mockInSrv *mocks.MockChatService_ConnectDirectMessageServer - var msg *pb.ChatMessage BeforeEach(func() { req = &pb.CharacterTarget{ Type: &pb.CharacterTarget_Id{Id: uint64(character.ID)}, } mockInSrv = mocks.NewMockChatService_ConnectDirectMessageServer(mockController) - msg = &pb.ChatMessage{ - Message: faker.Username(), - CharacterName: faker.Username(), - } }) When("given valid input", func() { It("should work for users with chat manager permissions (admin)", func() { + character.OwnerId = *admin.ID + mockChatService.EXPECT().DirectMessagesReader(gomock.Any(), character.Name).Return(kafka.NewReader(readerConfig)) + mockCharService.EXPECT(). + GetCharacter(gomock.Any(), gomock.Any()). + Return(character.ToPb(), nil) + mockInSrv.EXPECT().Context().Return(incAdminCtx).AnyTimes() + mockInSrv.EXPECT().Send(gomock.Any()).Return(io.EOF) + Eventually(writeMessageFunc).Within(time.Second * 15).Should(Succeed()) + Expect(server.ConnectDirectMessage(req, mockInSrv)).To(MatchError(io.EOF)) + }) + + It("should work for users with chat manager permissions (admin other)", func() { mockChatService.EXPECT().DirectMessagesReader(gomock.Any(), character.Name).Return(kafka.NewReader(readerConfig)) - mockCharService.EXPECT().GetAllCharactersForUser(gomock.Any(), gomock.Any()).Return(&pb.CharactersDetails{Characters: []*pb.CharacterDetails{character.ToPb()}}, nil) + mockCharService.EXPECT(). + GetCharacter(gomock.Any(), gomock.Any()). + Return(character.ToPb(), nil) mockInSrv.EXPECT().Context().Return(incAdminCtx).AnyTimes() mockInSrv.EXPECT().Send(gomock.Any()).Return(io.EOF) - Eventually(kafkaWriter.WriteMessages(context.Background(), kafka.Message{ - Key: []byte(msg.CharacterName), - Value: []byte(msg.Message), - })).Should(Succeed()) + Eventually(writeMessageFunc).Within(time.Second * 15).Should(Succeed()) Expect(server.ConnectDirectMessage(req, mockInSrv)).To(MatchError(io.EOF)) }) It("should work for users with chat permissions (player)", func() { + _, claims, err := helpers.VerifyClaims(incPlayerCtx, keycloak, conf.Chat.Keycloak.Realm) + Expect(err).NotTo(HaveOccurred()) + Expect(claims.Subject).To(Equal(character.OwnerId)) mockChatService.EXPECT().DirectMessagesReader(gomock.Any(), character.Name).Return(kafka.NewReader(readerConfig)) - mockCharService.EXPECT().GetAllCharactersForUser(gomock.Any(), gomock.Any()).Return(&pb.CharactersDetails{Characters: []*pb.CharacterDetails{character.ToPb()}}, nil) + mockCharService.EXPECT(). + GetCharacter(gomock.Any(), gomock.Any()). + Return(character.ToPb(), nil) mockInSrv.EXPECT().Context().Return(incPlayerCtx).AnyTimes() mockInSrv.EXPECT().Send(gomock.Any()).Return(io.EOF) - Eventually(kafkaWriter.WriteMessages(context.Background(), kafka.Message{ - Key: []byte(msg.CharacterName), - Value: []byte(msg.Message), - })).Within(time.Second * 5).Should(Succeed()) + Eventually(writeMessageFunc).Within(time.Second * 15).Should(Succeed()) Expect(server.ConnectDirectMessage(req, mockInSrv)).To(MatchError(io.EOF)) }) }) @@ -261,26 +285,27 @@ var _ = Describe("Chat", func() { }) It("should error if not owner of character (player)", func() { - mockCharService.EXPECT().GetAllCharactersForUser(gomock.Any(), gomock.Any()).Return(&pb.CharactersDetails{Characters: []*pb.CharacterDetails{}}, nil) + character.OwnerId = *admin.ID + mockCharService.EXPECT(). + GetCharacter(gomock.Any(), gomock.Any()). + Return(character.ToPb(), nil) mockInSrv.EXPECT().Context().Return(incPlayerCtx).AnyTimes() Expect(server.ConnectDirectMessage(req, mockInSrv)).To(MatchError(model.ErrUnauthorized)) }) - It("should error if not owner of character (adin)", func() { - mockCharService.EXPECT().GetAllCharactersForUser(gomock.Any(), gomock.Any()).Return(&pb.CharactersDetails{Characters: []*pb.CharacterDetails{}}, nil) - mockInSrv.EXPECT().Context().Return(incAdminCtx).AnyTimes() - Expect(server.ConnectDirectMessage(req, mockInSrv)).To(MatchError(model.ErrUnauthorized)) - }) - It("should error if getting characters has errors", func() { - mockCharService.EXPECT().GetAllCharactersForUser(gomock.Any(), gomock.Any()).Return(&pb.CharactersDetails{Characters: []*pb.CharacterDetails{}}, fakeErr) + mockCharService.EXPECT(). + GetCharacter(gomock.Any(), gomock.Any()). + Return(nil, fakeErr) mockInSrv.EXPECT().Context().Return(incPlayerCtx).AnyTimes() Expect(server.ConnectDirectMessage(req, mockInSrv)).NotTo(Succeed()) }) It("should error on invalid target type", func() { req.Type = nil - mockCharService.EXPECT().GetAllCharactersForUser(gomock.Any(), gomock.Any()).Return(&pb.CharactersDetails{Characters: []*pb.CharacterDetails{}}, fakeErr) + mockCharService.EXPECT(). + GetCharacter(gomock.Any(), gomock.Any()). + Return(nil, fakeErr) mockInSrv.EXPECT().Context().Return(incPlayerCtx).AnyTimes() Expect(server.ConnectDirectMessage(req, mockInSrv)).NotTo(Succeed()) }) @@ -293,18 +318,16 @@ var _ = Describe("Chat", func() { ) BeforeEach(func() { req = &pb.SendChatMessageRequest{ - ChannelId: uint64(chatChannel.ID), - ChatMessage: &pb.ChatMessage{ - Message: faker.Username(), - CharacterName: character.Name, - }, + ChannelId: uint64(chatChannel.ID), + ChatMessage: msg, } }) When("given valid input", func() { It("should work (admin)", func() { + character.OwnerId = *admin.ID mockCharService.EXPECT(). - GetAllCharactersForUser(gomock.Any(), gomock.Any()). - Return(&pb.CharactersDetails{Characters: []*pb.CharacterDetails{character.ToPb()}}, nil) + GetCharacter(gomock.Any(), gomock.Any()). + Return(character.ToPb(), nil) mockChatService.EXPECT(). SendChannelMessage(gomock.Any(), gomock.Any(), gomock.Any(), uint(req.ChannelId)). Return(nil) @@ -314,9 +337,10 @@ var _ = Describe("Chat", func() { }) It("should work (player)", func() { + Expect(character.OwnerId).To(Equal(*player.ID)) mockCharService.EXPECT(). - GetAllCharactersForUser(gomock.Any(), gomock.Any()). - Return(&pb.CharactersDetails{Characters: []*pb.CharacterDetails{character.ToPb()}}, nil) + GetCharacter(gomock.Any(), gomock.Any()). + Return(character.ToPb(), nil) mockChatService.EXPECT(). AuthorizedChannelsForCharacter(gomock.Any(), character.ID). Return(model.ChatChannels{chatChannel}, nil) @@ -348,17 +372,18 @@ var _ = Describe("Chat", func() { It("should err if not owner (admin)", func() { mockCharService.EXPECT(). - GetAllCharactersForUser(gomock.Any(), gomock.Any()). - Return(&pb.CharactersDetails{Characters: []*pb.CharacterDetails{}}, nil) + GetCharacter(gomock.Any(), gomock.Any()). + Return(character.ToPb(), nil) out, err := server.SendChatMessage(incAdminCtx, req) Expect(err).To(HaveOccurred()) Expect(out).To(BeNil()) }) It("should err if not owner (player)", func() { + character.OwnerId = *admin.ID mockCharService.EXPECT(). - GetAllCharactersForUser(gomock.Any(), gomock.Any()). - Return(&pb.CharactersDetails{Characters: []*pb.CharacterDetails{}}, nil) + GetCharacter(gomock.Any(), gomock.Any()). + Return(character.ToPb(), nil) out, err := server.SendChatMessage(incPlayerCtx, req) Expect(err).To(HaveOccurred()) Expect(out).To(BeNil()) @@ -366,8 +391,8 @@ var _ = Describe("Chat", func() { It("should err if no channel permission (player)", func() { mockCharService.EXPECT(). - GetAllCharactersForUser(gomock.Any(), gomock.Any()). - Return(&pb.CharactersDetails{Characters: []*pb.CharacterDetails{character.ToPb()}}, nil) + GetCharacter(gomock.Any(), gomock.Any()). + Return(character.ToPb(), nil) mockChatService.EXPECT(). AuthorizedChannelsForCharacter(gomock.Any(), character.ID). Return(model.ChatChannels{}, nil) @@ -378,7 +403,7 @@ var _ = Describe("Chat", func() { It("should err if verify user errors", func() { mockCharService.EXPECT(). - GetAllCharactersForUser(gomock.Any(), gomock.Any()). + GetCharacter(gomock.Any(), gomock.Any()). Return(nil, fakeErr) out, err := server.SendChatMessage(incAdminCtx, req) Expect(err).To(HaveOccurred()) @@ -387,8 +412,8 @@ var _ = Describe("Chat", func() { It("should err if getting authorized channels fails", func() { mockCharService.EXPECT(). - GetAllCharactersForUser(gomock.Any(), gomock.Any()). - Return(&pb.CharactersDetails{Characters: []*pb.CharacterDetails{character.ToPb()}}, nil) + GetCharacter(gomock.Any(), gomock.Any()). + Return(character.ToPb(), nil) mockChatService.EXPECT(). AuthorizedChannelsForCharacter(gomock.Any(), character.ID). Return(nil, fakeErr) @@ -399,12 +424,15 @@ var _ = Describe("Chat", func() { It("should error if sending message fails", func() { mockCharService.EXPECT(). - GetAllCharactersForUser(gomock.Any(), gomock.Any()). - Return(&pb.CharactersDetails{Characters: []*pb.CharacterDetails{character.ToPb()}}, nil) + GetCharacter(gomock.Any(), gomock.Any()). + Return(character.ToPb(), nil) + mockChatService.EXPECT(). + AuthorizedChannelsForCharacter(gomock.Any(), character.ID). + Return(model.ChatChannels{chatChannel}, nil) mockChatService.EXPECT(). SendChannelMessage(gomock.Any(), gomock.Any(), gomock.Any(), uint(req.ChannelId)). Return(fakeErr) - out, err := server.SendChatMessage(incAdminCtx, req) + out, err := server.SendChatMessage(incPlayerCtx, req) Expect(err).To(HaveOccurred()) Expect(out).To(BeNil()) }) @@ -422,14 +450,15 @@ var _ = Describe("Chat", func() { Name: character.Name, }, }, - ChatMessage: &pb.ChatMessage{Message: faker.Username(), CharacterName: character.Name}, + ChatMessage: msg, } }) When("given valid input", func() { It("should work (admin)", func() { + character.OwnerId = *admin.ID mockCharService.EXPECT(). - GetAllCharactersForUser(gomock.Any(), gomock.Any()). - Return(&pb.CharactersDetails{Characters: []*pb.CharacterDetails{character.ToPb()}}, nil) + GetCharacter(gomock.Any(), gomock.Any()). + Return(character.ToPb(), nil) mockChatService.EXPECT(). SendDirectMessage(gomock.Any(), gomock.Any(), gomock.Any(), character.Name). Return(nil) @@ -439,9 +468,10 @@ var _ = Describe("Chat", func() { }) It("should work (player)", func() { + character.OwnerId = *player.ID mockCharService.EXPECT(). - GetAllCharactersForUser(gomock.Any(), gomock.Any()). - Return(&pb.CharactersDetails{Characters: []*pb.CharacterDetails{character.ToPb()}}, nil) + GetCharacter(gomock.Any(), gomock.Any()). + Return(character.ToPb(), nil) mockChatService.EXPECT(). SendDirectMessage(gomock.Any(), gomock.Any(), gomock.Any(), character.Name). Return(nil) @@ -470,17 +500,18 @@ var _ = Describe("Chat", func() { It("should err if not owner (admin)", func() { mockCharService.EXPECT(). - GetAllCharactersForUser(gomock.Any(), gomock.Any()). - Return(&pb.CharactersDetails{Characters: []*pb.CharacterDetails{}}, nil) + GetCharacter(gomock.Any(), gomock.Any()). + Return(character.ToPb(), nil) out, err := server.SendDirectMessage(incAdminCtx, req) Expect(err).To(HaveOccurred()) Expect(out).To(BeNil()) }) It("should err if not owner (player)", func() { + character.OwnerId = *admin.ID mockCharService.EXPECT(). - GetAllCharactersForUser(gomock.Any(), gomock.Any()). - Return(&pb.CharactersDetails{Characters: []*pb.CharacterDetails{}}, nil) + GetCharacter(gomock.Any(), gomock.Any()). + Return(character.ToPb(), nil) out, err := server.SendDirectMessage(incPlayerCtx, req) Expect(err).To(HaveOccurred()) Expect(out).To(BeNil()) @@ -488,7 +519,7 @@ var _ = Describe("Chat", func() { It("should err if verify user errors", func() { mockCharService.EXPECT(). - GetAllCharactersForUser(gomock.Any(), gomock.Any()). + GetCharacter(gomock.Any(), gomock.Any()). Return(nil, fakeErr) out, err := server.SendDirectMessage(incAdminCtx, req) Expect(err).To(HaveOccurred()) @@ -497,16 +528,510 @@ var _ = Describe("Chat", func() { It("should error if sending message fails", func() { mockCharService.EXPECT(). - GetAllCharactersForUser(gomock.Any(), gomock.Any()). - Return(&pb.CharactersDetails{Characters: []*pb.CharacterDetails{character.ToPb()}}, nil) + GetCharacter(gomock.Any(), gomock.Any()). + Return(character.ToPb(), nil) mockChatService.EXPECT(). SendDirectMessage(gomock.Any(), gomock.Any(), gomock.Any(), character.Name). Return(fakeErr) - out, err := server.SendDirectMessage(incAdminCtx, req) + out, err := server.SendDirectMessage(incPlayerCtx, req) Expect(err).To(HaveOccurred()) Expect(out).To(BeNil()) }) }) }) }) + + Describe("GetChannel", func() { + var ( + req *pb.ChatChannelTarget + ) + BeforeEach(func() { + req = &pb.ChatChannelTarget{ + Id: uint64(chatChannel.ID), + } + }) + When("given valid input", func() { + It("should work (admin)", func() { + mockChatService.EXPECT().GetChannel(gomock.Any(), chatChannel.ID).Return(chatChannel, nil) + out, err := server.GetChannel(incAdminCtx, req) + Expect(err).NotTo(HaveOccurred()) + Expect(out).To(BeEquivalentTo(chatChannel.ToPb())) + }) + }) + + When("given invalid input", func() { + It("should error if invalid context (nil)", func() { + out, err := server.GetChannel(nil, req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + + It("should error if invalid context (no claims)", func() { + out, err := server.GetChannel(context.Background(), req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + + It("should error if invalid permission (player)", func() { + out, err := server.GetChannel(incPlayerCtx, req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + + It("should error if invalid permission (guest)", func() { + out, err := server.GetChannel(incGuestCtx, req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + + It("should error if getting channel errors", func() { + mockChatService.EXPECT().GetChannel(gomock.Any(), chatChannel.ID).Return(nil, fakeErr) + out, err := server.GetChannel(incAdminCtx, req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + + It("should error if no channel exists", func() { + mockChatService.EXPECT().GetChannel(gomock.Any(), chatChannel.ID).Return(nil, nil) + out, err := server.GetChannel(incAdminCtx, req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + }) + }) + + Describe("CreateChannel", func() { + var ( + req *pb.CreateChannelMessage + ) + BeforeEach(func() { + req = &pb.CreateChannelMessage{ + Name: faker.Username(), + Dimension: faker.Username(), + } + }) + When("given valid input", func() { + It("should work (admin)", func() { + mockChatService.EXPECT(). + CreateChannel(gomock.Any(), gomock.Eq(&model.ChatChannel{Name: req.Name, Dimension: req.Dimension})). + Return(nil, nil) + out, err := server.CreateChannel(incAdminCtx, req) + Expect(err).NotTo(HaveOccurred()) + Expect(out).NotTo(BeNil()) + }) + }) + + When("given invalid input", func() { + It("should error if invalid context (nil)", func() { + out, err := server.CreateChannel(nil, req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + + It("should error if invalid context (no claims)", func() { + out, err := server.CreateChannel(context.Background(), req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + + It("should error if invalid permission (player)", func() { + out, err := server.CreateChannel(incPlayerCtx, req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + + It("should error if invalid permission (guest)", func() { + out, err := server.CreateChannel(incGuestCtx, req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + + It("should error if error during creation", func() { + mockChatService.EXPECT(). + CreateChannel(gomock.Any(), gomock.Eq(&model.ChatChannel{Name: req.Name, Dimension: req.Dimension})). + Return(nil, fakeErr) + out, err := server.CreateChannel(incAdminCtx, req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + + It("should unique error if name is taken", func() { + mockChatService.EXPECT(). + CreateChannel(gomock.Any(), gomock.Eq(&model.ChatChannel{Name: req.Name, Dimension: req.Dimension})). + Return(nil, gorm.ErrDuplicatedKey) + out, err := server.CreateChannel(incAdminCtx, req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + }) + }) + + Describe("DeleteChannel", func() { + var ( + req *pb.ChatChannelTarget + ) + BeforeEach(func() { + req = &pb.ChatChannelTarget{ + Id: uint64(chatChannel.ID), + } + }) + When("given valid input", func() { + It("should work (admin)", func() { + mockChatService.EXPECT(). + DeleteChannel(gomock.Any(), gomock.Any()). + Return(nil) + out, err := server.DeleteChannel(incAdminCtx, req) + Expect(err).NotTo(HaveOccurred()) + Expect(out).NotTo(BeNil()) + }) + }) + + When("given invalid input", func() { + It("should error if invalid context (nil)", func() { + out, err := server.DeleteChannel(nil, req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + + It("should error if invalid context (no claims)", func() { + out, err := server.DeleteChannel(context.Background(), req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + + It("should error if invalid permission (player)", func() { + out, err := server.DeleteChannel(incPlayerCtx, req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + + It("should error if invalid permission (guest)", func() { + out, err := server.DeleteChannel(incGuestCtx, req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + + It("should error if error during creation", func() { + mockChatService.EXPECT(). + DeleteChannel(gomock.Any(), gomock.Any()). + Return(fakeErr) + out, err := server.DeleteChannel(incAdminCtx, req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + + It("should unique error if not found is taken", func() { + mockChatService.EXPECT(). + DeleteChannel(gomock.Any(), gomock.Any()). + Return(gorm.ErrRecordNotFound) + out, err := server.DeleteChannel(incAdminCtx, req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + }) + }) + + Describe("EditChannel", func() { + var ( + req *pb.UpdateChatChannelRequest + ) + BeforeEach(func() { + req = &pb.UpdateChatChannelRequest{ + ChannelId: uint64(chatChannel.ID), + OptionalName: &pb.UpdateChatChannelRequest_Name{Name: faker.Username()}, + OptionalDimension: &pb.UpdateChatChannelRequest_Dimension{Dimension: faker.Username()}, + } + }) + When("given valid input", func() { + It("should work (admin)", func() { + mockChatService.EXPECT(). + UpdateChannel(gomock.Any(), req). + Return(chatChannel, nil) + out, err := server.EditChannel(incAdminCtx, req) + Expect(err).NotTo(HaveOccurred()) + Expect(out).NotTo(BeNil()) + }) + }) + + When("given invalid input", func() { + It("should error if invalid context (nil)", func() { + out, err := server.EditChannel(nil, req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + + It("should error if invalid context (no claims)", func() { + out, err := server.EditChannel(context.Background(), req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + + It("should error if invalid permission (player)", func() { + out, err := server.EditChannel(incPlayerCtx, req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + + It("should error if invalid permission (guest)", func() { + out, err := server.EditChannel(incGuestCtx, req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + + It("should error if error during creation", func() { + mockChatService.EXPECT(). + UpdateChannel(gomock.Any(), req). + Return(nil, fakeErr) + out, err := server.EditChannel(incAdminCtx, req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + + It("should unique error if not found is taken", func() { + mockChatService.EXPECT(). + UpdateChannel(gomock.Any(), req). + Return(nil, gorm.ErrRecordNotFound) + out, err := server.EditChannel(incAdminCtx, req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + }) + }) + + Describe("AllChatChannel", func() { + var ( + req *emptypb.Empty + ) + BeforeEach(func() { + req = &emptypb.Empty{} + }) + + When("given valid input", func() { + It("should work (admin)", func() { + mockChatService.EXPECT(). + AllChannels(gomock.Any()). + Return(model.ChatChannels{chatChannel}, nil) + out, err := server.AllChatChannels(incAdminCtx, req) + Expect(err).NotTo(HaveOccurred()) + Expect(out).NotTo(BeNil()) + }) + }) + + When("given invalid input", func() { + It("should error if invalid context (nil)", func() { + out, err := server.AllChatChannels(nil, req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + + It("should error if invalid context (no claims)", func() { + out, err := server.AllChatChannels(context.Background(), req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + + It("should error if invalid permission (player)", func() { + out, err := server.AllChatChannels(incPlayerCtx, req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + + It("should error if invalid permission (guest)", func() { + out, err := server.AllChatChannels(incGuestCtx, req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + + It("should error if error during creation", func() { + mockChatService.EXPECT(). + AllChannels(gomock.Any()). + Return(nil, fakeErr) + out, err := server.AllChatChannels(incAdminCtx, req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + }) + }) + + Describe("GetAuthorizedChatChannel", func() { + var ( + req *pb.CharacterTarget + ) + BeforeEach(func() { + req = &pb.CharacterTarget{ + Type: &pb.CharacterTarget_Id{ + Id: uint64(character.ID), + }, + } + }) + When("given valid input", func() { + It("should work (admin self)", func() { + character.OwnerId = *admin.ID + mockChatService.EXPECT(). + AuthorizedChannelsForCharacter(gomock.Any(), character.ID). + Return(model.ChatChannels{chatChannel}, nil) + mockCharService.EXPECT(). + GetCharacter(gomock.Any(), req). + Return(character.ToPb(), nil) + out, err := server.GetAuthorizedChatChannels(incAdminCtx, req) + Expect(err).NotTo(HaveOccurred()) + Expect(out.Channels).To(HaveLen(1)) + }) + + It("should work (admin other)", func() { + mockChatService.EXPECT(). + AuthorizedChannelsForCharacter(gomock.Any(), character.ID). + Return(model.ChatChannels{chatChannel}, nil) + mockCharService.EXPECT(). + GetCharacter(gomock.Any(), req). + Return(character.ToPb(), nil) + out, err := server.GetAuthorizedChatChannels(incAdminCtx, req) + Expect(err).NotTo(HaveOccurred()) + Expect(out.Channels).To(HaveLen(1)) + }) + + It("should work (player self)", func() { + mockChatService.EXPECT(). + AuthorizedChannelsForCharacter(gomock.Any(), character.ID). + Return(model.ChatChannels{chatChannel}, nil) + mockCharService.EXPECT(). + GetCharacter(gomock.Any(), req). + Return(character.ToPb(), nil) + out, err := server.GetAuthorizedChatChannels(incPlayerCtx, req) + Expect(err).NotTo(HaveOccurred()) + Expect(out.Channels).To(HaveLen(1)) + }) + }) + + When("given invalid input", func() { + It("should error if invalid context (nil)", func() { + out, err := server.GetAuthorizedChatChannels(nil, req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + + It("should error if invalid context (no claims)", func() { + out, err := server.GetAuthorizedChatChannels(context.Background(), req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + + It("should error if invalid permission (guest)", func() { + out, err := server.GetAuthorizedChatChannels(incGuestCtx, req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + + It("should error if invalid permission (player other)", func() { + character.OwnerId = *admin.ID + mockChatService.EXPECT(). + AuthorizedChannelsForCharacter(gomock.Any(), character.ID). + Return(nil, fakeErr) + mockCharService.EXPECT(). + GetCharacter(gomock.Any(), gomock.Any()). + Return(character.ToPb(), nil) + out, err := server.GetAuthorizedChatChannels(incAdminCtx, req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + + It("should error if getting character failed", func() { + character.OwnerId = *admin.ID + mockCharService.EXPECT(). + GetCharacter(gomock.Any(), req). + Return(nil, fakeErr) + out, err := server.GetAuthorizedChatChannels(incAdminCtx, req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + + It("should error if no character is found", func() { + character.OwnerId = *admin.ID + mockCharService.EXPECT(). + GetCharacter(gomock.Any(), req). + Return(nil, nil) + out, err := server.GetAuthorizedChatChannels(incAdminCtx, req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + }) + }) + + Describe("UpdateUserchatChannelAuthorizations", func() { + var ( + req *pb.RequestChatChannelAuthChange + ) + BeforeEach(func() { + req = &pb.RequestChatChannelAuthChange{ + Character: &pb.CharacterTarget{ + Type: &pb.CharacterTarget_Id{ + Id: uint64(character.ID), + }, + }, + Add: true, + Ids: []uint64{1, 2, 3}, + } + }) + When("given valid input", func() { + It("should work (admin)", func() { + mockChatService.EXPECT(). + ChangeAuthorizationForCharacter(gomock.Any(), character.ID, *helpers.ArrayOfUint64ToUint(&req.Ids), req.Add). + Return(nil) + out, err := server.UpdateUserChatChannelAuthorizations(incAdminCtx, req) + Expect(err).NotTo(HaveOccurred()) + Expect(out).NotTo(BeNil()) + }) + }) + + When("given invalid input", func() { + It("should error if invalid context (nil)", func() { + out, err := server.UpdateUserChatChannelAuthorizations(nil, req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + + It("should error if invalid context (no claims)", func() { + out, err := server.UpdateUserChatChannelAuthorizations(context.Background(), req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + + It("should error if invalid permission (player)", func() { + out, err := server.UpdateUserChatChannelAuthorizations(incPlayerCtx, req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + + It("should error if invalid permission (guest)", func() { + out, err := server.UpdateUserChatChannelAuthorizations(incGuestCtx, req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + + It("should error if error during getting character target", func() { + req.Character.Type = nil + out, err := server.UpdateUserChatChannelAuthorizations(incGuestCtx, req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + + It("should error if error during update", func() { + mockChatService.EXPECT(). + ChangeAuthorizationForCharacter(gomock.Any(), character.ID, *helpers.ArrayOfUint64ToUint(&req.Ids), req.Add). + Return(fakeErr) + out, err := server.UpdateUserChatChannelAuthorizations(incAdminCtx, req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + + It("should unique error if conflict exists", func() { + mockChatService.EXPECT(). + ChangeAuthorizationForCharacter(gomock.Any(), character.ID, *helpers.ArrayOfUint64ToUint(&req.Ids), req.Add). + Return(gorm.ErrDuplicatedKey) + out, err := server.UpdateUserChatChannelAuthorizations(incAdminCtx, req) + Expect(err).To(HaveOccurred()) + Expect(out).To(BeNil()) + }) + }) + }) })